import { addComponent, defineComponent, Types, type Entity, type IWorld } from '$lib/ecs';
import { getPlayer } from '$lib/player';
import { hasPos3, placeOnMap } from '$lib/pos3';
import { random, randomBetweenInclusive } from '$lib/random';
import { decode } from '$lib/util';
import { newIntroMission } from './intro';

export const OnMission = defineComponent('OnMission', {
  lastMission: Types.eid,
  mission: Types.eid,
});

export const Mission = defineComponent('Mission', {
  floorCount: [Types.ui16, 2],
  template: [Types.ui8, 32],
});

type MissionTemplate = {
  generate: (world: IWorld, floorCount: number, minSize: number, maxSize: number) => [number, number, number],
  onEntrance: (world: IWorld, pc: Entity) => void,
};

const missionTemplates = new Map<string, MissionTemplate>();

export const registerMissionTemplate = (name: string, tmplt: MissionTemplate) => {
  missionTemplates.set(name, tmplt);
};

export const setMission = (world: IWorld, pc: Entity, mission: Entity) => {
  addComponent(world, OnMission, pc);
  OnMission.lastMission[pc] = OnMission.mission[pc];
  OnMission.mission[pc] = mission;
};

export const ensureMission = (world: IWorld) => {
  const pc = getPlayer(world);
  if (!hasPos3(world, pc)) {
    let mission = OnMission.mission[pc];
    if (mission === 0) {
      mission = newIntroMission(world);
    }
    prepareMission(world, mission, pc);
  }
};

const prepareMission = (world, mission, pc) => {
  const floorCount = randomBetweenInclusive(...Mission.floorCount[mission]);
  console.log(floorCount);
  const tmpltName = decode(Mission.template[mission]);
  console.log(tmpltName);
  const tmplt = missionTemplates.get(tmpltName);
  if (tmplt === undefined) {
    console.warn("Cannot find mission template", tmpltName);
    return;
  }
  const [x, y, z] = tmplt.generate(world, floorCount);
  placeOnMap(world, pc, x, y, z);
  tmplt.onEntrance(world, pc);
};
